package com.xuebusi.toutiao.admin.api.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuebusi.toutiao.admin.api.common.config.GlobalConfig;
import com.xuebusi.toutiao.admin.api.common.enums.TokenEnum;
import com.xuebusi.toutiao.admin.api.common.exception.CustomException;
import com.xuebusi.toutiao.admin.api.common.result.ApiResult;
import com.xuebusi.toutiao.admin.api.common.util.FileUtil;
import com.xuebusi.toutiao.admin.api.common.util.JwtUtil;
import com.xuebusi.toutiao.admin.api.user.dao.UserDao;
import com.xuebusi.toutiao.admin.api.user.entity.CollectEntity;
import com.xuebusi.toutiao.admin.api.user.entity.SourceEntity;
import com.xuebusi.toutiao.admin.api.user.entity.UserEntity;
import com.xuebusi.toutiao.admin.api.user.enums.CollectType;
import com.xuebusi.toutiao.admin.api.user.enums.SourceType;
import com.xuebusi.toutiao.admin.api.user.form.LoginForm;
import com.xuebusi.toutiao.admin.api.user.form.RegisterForm;
import com.xuebusi.toutiao.admin.api.user.form.UserForm;
import com.xuebusi.toutiao.admin.api.user.service.CollectService;
import com.xuebusi.toutiao.admin.api.user.service.SourceService;
import com.xuebusi.toutiao.admin.api.user.service.UserService;
import com.xuebusi.toutiao.admin.api.user.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

/**
 * 用户服务实现类
 */
@Slf4j
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
    @Resource
    private GlobalConfig globalConfig;

    @Resource
    private CollectService collectService;

    @Resource
    private SourceService sourceService;

    /**
     * 用户登录
     *
     * @param loginForm 登录表单
     * @return token信息
     */
    @Override
    public ResponseEntity<ApiResult<UserTokenVO>> authorizations(LoginForm loginForm) {
        // 根据手机号查询用户
        UserEntity userEntity = this.getOne(new QueryWrapper<UserEntity>().eq("mobile", loginForm.getMobile()));
        if (userEntity == null) {
            throw new CustomException("用户不存在，请先注册", 401);
        }
        // 生成token和refresh_token
        String token = JwtUtil.generalToken(userEntity, TokenEnum.TOKEN);
        String refreshToken = JwtUtil.generalToken(userEntity, TokenEnum.REFRESH_TOKEN);
        // 响应结果
        UserTokenVO tokenVO = new UserTokenVO();
        tokenVO.setId(userEntity.getId());
        tokenVO.setName(userEntity.getName());
        tokenVO.setPhoto(globalConfig.getWebSite() + userEntity.getPhoto());
        tokenVO.setToken(token);
        tokenVO.setRefresh_token(refreshToken);
        return new ResponseEntity<>(ApiResult.ok(tokenVO), HttpStatus.CREATED);
    }

    /**
     * 用户注册
     *
     * @param registerForm 注册表单
     * @return 用户信息
     */
    @Override
    public ResponseEntity<ApiResult<UserEntity>> register(RegisterForm registerForm) {
        // 是否已经注册了
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<UserEntity>()
                .eq("mobile", registerForm.getMobile());
        UserEntity existUserEntity = this.getOne(queryWrapper);
        if (existUserEntity != null) {
            throw new CustomException("已经注册过了,请直接登录", 402);
        }
        // 保存注册信息
        UserEntity newUserEntity = new UserEntity();
        newUserEntity.setName(registerForm.getName());
        newUserEntity.setPhoto(registerForm.getPhoto());
        newUserEntity.setMobile(registerForm.getMobile());
        this.save(newUserEntity);
        return new ResponseEntity<>(ApiResult.ok(newUserEntity), HttpStatus.CREATED);
    }

    /**
     * 修改用户头像
     *
     * @param file    文件
     * @param userId  用户id
     * @param request request
     * @return
     */
    @Override
    public ResponseEntity<ApiResult<UserPhotoVO>> updatePhoto(
            MultipartFile file, Integer userId, HttpServletRequest request) {
        // 根据用户id查询用户信息
        UserEntity userEntity = this.getById(userId);
        if (userEntity == null) {
            throw new CustomException("用户不存在", 501);
        }
        String photoUrl;
        try {
            // 上传图片到文件服务器
            photoUrl = FileUtil.upload(file, request, globalConfig.getUploadPath());
        } catch (IOException e) {
            throw new CustomException("上传用户头像失败", 500);
        }
        UserEntity updateUser = new UserEntity();
        updateUser.setId(userId);
        updateUser.setPhoto(photoUrl);
        this.updateById(updateUser);
        UserPhotoVO userPhotoVO = new UserPhotoVO(userId, globalConfig.getWebSite() + photoUrl);
        return ResponseEntity.ok(ApiResult.ok(userPhotoVO));
    }

    /**
     * 修改用户资料
     *
     * @param userId   用户id
     * @param userForm 修改表单
     * @return
     * @throws CustomException
     */
    @Override
    public ResponseEntity<ApiResult<UserProfileVO>> updateUserProfile(
            Integer userId, UserForm userForm) throws CustomException {
        UserEntity userEntity = this.getById(userId);
        if (userEntity == null) {
            throw new CustomException("用户不存在", 401);
        }
        UserEntity updateUser = new UserEntity();
        updateUser.setId(userId);
        updateUser.setName(userForm.getName());
        updateUser.setIntro(userForm.getIntro());
        updateUser.setEmail(userForm.getEmail());
        this.updateById(updateUser);
        UserProfileVO userProfileVO = new UserProfileVO();
        BeanUtils.copyProperties(updateUser, userProfileVO);
        ApiResult apiResult = ApiResult.ok(userProfileVO);
        return new ResponseEntity<>(apiResult, HttpStatus.CREATED);
    }

    /**
     * 查询用户资料
     *
     * @param userId
     * @return
     */
    @Override
    public ResponseEntity<ApiResult<UserDetailVO>> getUserProfile(Integer userId) {
        UserEntity userEntity = this.getById(userId);
        if (userEntity == null) {
            throw new CustomException("用户不存在", 401);
        }
        UserDetailVO userDetailVO = new UserDetailVO();
        BeanUtils.copyProperties(userEntity, userDetailVO);
        userDetailVO.setPhoto(globalConfig.getWebSite() + userDetailVO.getPhoto());
        ApiResult apiResult = ApiResult.ok(userDetailVO);
        return new ResponseEntity<>(apiResult, HttpStatus.CREATED);
    }

    /**
     * 刷新token
     *
     * @param auth
     * @return
     */
    @Override
    public ResponseEntity<ApiResult<RefreshTokenVO>> refreshToken(String auth) {
        log.info(">>> {}", auth);
        if (!StringUtils.hasLength(auth)
                || !auth.startsWith("Bearer ")
                || auth.split(" ").length != 2) {
            throw new CustomException("Token格式非法", 400);
        }
        String refreshToken = auth.split(" ")[1];
        UserEntity userEntity = JwtUtil.resolveUserInfo(refreshToken);
        String token = JwtUtil.generalToken(userEntity, TokenEnum.TOKEN);
        RefreshTokenVO refreshTokenVO = new RefreshTokenVO(token);
        ApiResult apiResult = ApiResult.ok(refreshTokenVO);
        return new ResponseEntity<>(apiResult, HttpStatus.CREATED);
    }

    /**
     * 收藏 or 取消收藏
     *
     * @param userId   用户id
     * @param sourceId 资源id
     * @param collect  是否收藏
     * @return
     */
    @Override
    public ResponseEntity<ApiResult<CollectRVO>> collect(Integer userId, Integer sourceId, Boolean collect) {
        if (collect) {
            CollectEntity collectEntity = new CollectEntity();
            collectEntity.setUserId(userId);
            collectEntity.setType(CollectType.IMAGE.getCode());
            collectEntity.setSourceId(sourceId);
            collectEntity.setCreateTime(new Date());
            return collectService.collect(collectEntity);
        } else {
            return collectService.cancel(userId, sourceId, CollectType.IMAGE.getCode());
        }
    }

    /**
     * 上传图片素材
     *
     * @param userId  用户id
     * @param file    图片文件
     * @param request request
     * @throws CustomException
     */
    @Override
    public ResponseEntity<ApiResult<SourceEntity>> uploadImage(Integer userId, MultipartFile file, HttpServletRequest request) throws CustomException {
        String sourcePath;
        try {
            sourcePath = FileUtil.upload(file, request, globalConfig.getUploadPath());
        } catch (IOException e) {
            log.error(">>> userId:{}, fileName:{}", userId, file.getOriginalFilename());
            throw new CustomException("图片上传失败", 507);
        }
        SourceEntity sourceEntity = new SourceEntity();
        sourceEntity.setUrl(sourcePath);
        sourceEntity.setType(SourceType.IMAGE.getCode());
        sourceEntity.setUserId(userId);
        sourceEntity.setIsActive(true);
        sourceEntity.setCreateTime(new Date());
        sourceService.save(sourceEntity);
        // 返回完整图片URL
        sourceEntity.setUrl(globalConfig.getWebSite() + sourcePath);
        return ResponseEntity.ok(ApiResult.ok(sourceEntity));
    }

    /**
     * 删除图片素材
     *
     * @param userId   用户id
     * @param sourceId 资源id
     * @return
     */
    @Override
    public ResponseEntity deleteImage(Integer userId, Integer sourceId) {
        log.info(">>> userId:{}, sourceId:{}", userId, sourceId);
        sourceService.removeById(sourceId);
        // TODO 根据图片路径将磁盘上对应的图片删除
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }
}
